﻿using System;
using System.Web;
using MugenInjection.Web.Interface;

namespace MugenInjection.Web.Scope
{
    /// <summary>
    /// Represents the scope provider for <see cref="HttpContext"/>.
    /// </summary>
    public sealed class HttpRequestScopeProvider : IScopeProvider
    {
        #region Fields

        private readonly IApplicationConfiguration _applicationConfiguration;

        #endregion

        #region Constructor

        /// <summary>
        /// Initializes a new instance of the <see cref="HttpRequestScopeProvider"/> class.
        /// </summary>
        public HttpRequestScopeProvider(IApplicationConfiguration applicationConfiguration)
        {
            _applicationConfiguration = applicationConfiguration;
            _applicationConfiguration.EndRequest += ApplicationConfigurationOnEndRequest;
        }

        #endregion

        #region Events

        private void OnReleaseScope(object scope)
        {
            Action<object> handler = ReleaseScope;
            if (handler != null)
                handler(scope);
        }

        private void ApplicationConfigurationOnEndRequest(MugenInjectionHttpApplication mugenInjectionHttpApplication)
        {
            object currentScope = ValidateContext(mugenInjectionHttpApplication.Context);
            OnReleaseScope(currentScope);
        }

        private static HttpContext ValidateContext(HttpContext httpContext)
        {
//            return httpContext;
             if (httpContext == null)
                 throw new InvalidOperationException(
                    "There is no current HttpContext, HttpRequestScopeProvider can't access to the current HttpContext.");
            return httpContext;
        }

        #endregion

        #region Implementation of IScopeProvider

        /// <summary>
        /// Occured when need dispose scope.
        /// </summary>
        public event Action<object> ReleaseScope;

        /// <summary>
        /// Gets the current scope.
        /// </summary>
        /// <returns></returns>
        public object GetCurrentScope()
        {
            return ValidateContext(HttpContext.Current);
        }

        #endregion
    }
}